package com.dpiinc.TechPage.oss

import android.app.Application
import android.text.Html
import com.dpiinc.TechPage.AWLog
import com.liulishuo.filedownloader.BaseDownloadTask
import com.liulishuo.filedownloader.FileDownloadQueueSet
import com.liulishuo.filedownloader.FileDownloadSampleListener
import com.liulishuo.filedownloader.FileDownloader
import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection
import com.liulishuo.filedownloader.util.FileDownloadUtils

/**
 * 文件下载
 * //TODO 待整理
 * Created by X on 2018/7/31.
 */
object FileDownloadHelper {

    private const val TAG = "FileDownloadHelper"

    private var downloadSuccessCount = 0
    private var downloadFailedCount = 0

    fun init(application: Application) {
        FileDownloader.setupOnApplicationOnCreate(application)
                .connectionCreator(FileDownloadUrlConnection.Creator(FileDownloadUrlConnection.Configuration()
                        .connectTimeout(15000) // set connection timeout.
                        .readTimeout(15000) // set read timeout.
                ))
                .commit()
    }

    private fun reset() {
        downloadSuccessCount = 0
        downloadFailedCount = 0
    }

    fun downloadFiles(files: List<DownloadTask>, progressCallback: (DownloadTask, Float, Boolean) -> Unit) {
        reset()
        val updateTaskList = ArrayList<BaseDownloadTask>()
        files.forEach {
            if (it.url.isEmpty()) {
                return@forEach
            }
            updateTaskList.add(FileDownloader.getImpl().create(it.url)
                    .setTag(it).setPath(it.targetFilePath))
        }
        //TODO 空任务列表，直接返回
        if (updateTaskList.isEmpty()) {
            progressCallback(DownloadTask("", ""), 1f, true)
        }
        FileDownloadQueueSet(createListener(progressCallback, updateTaskList.size))
                .setForceReDownload(true)
//                .setDirectory(downloadDir)
                .setCallbackProgressTimes(100)
//                .downloadSequentially(updateTaskList)
                .downloadTogether(updateTaskList)
                .start()

    }

    @Synchronized
    private fun onDownloadSuccess(task: DownloadTask, progressCallback: (DownloadTask, Float, Boolean) -> Unit, totalCount: Int) {
        synchronized(downloadSuccessCount) {
            downloadSuccessCount++
            progressCallback(task, downloadSuccessCount.toFloat() / totalCount, checkIfDownloadComplete(totalCount))
        }
    }

    @Synchronized
    private fun onDownloadFailed(task: DownloadTask, progressCallback: (DownloadTask, Float, Boolean) -> Unit, totalCount: Int) {
        synchronized(downloadFailedCount) {
            downloadFailedCount++
            progressCallback(task, downloadSuccessCount.toFloat() / totalCount, checkIfDownloadComplete(totalCount))
        }
    }

    @Synchronized
    private fun checkIfDownloadComplete(totalCount: Int): Boolean {
        return (downloadSuccessCount + downloadFailedCount == totalCount)
    }

    private fun createListener(progressCallback: (DownloadTask, Float, Boolean) -> Unit, totalCount: Int): FileDownloadSampleListener {
        return object : FileDownloadSampleListener() {

            override fun pending(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
                log(String.format("[pending] tag[%s] %d/%d", task.tag, soFarBytes, totalBytes))
            }

            override fun connected(task: BaseDownloadTask?, etag: String?, isContinue: Boolean, soFarBytes: Int, totalBytes: Int) {
                super.connected(task, etag, isContinue, soFarBytes, totalBytes)
                log(String.format("[connected] tag[%s] %s %B %d/%d", task!!.tag, etag, isContinue, soFarBytes, totalBytes))
            }

            override fun progress(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
                log(String.format("[progress] tag[%s] %d/%d", task.tag, soFarBytes, totalBytes))
                val progress = (soFarBytes.toFloat() / totalBytes * 100).toInt()
//                updateStatus(task.tag, FileDownloadStatus.DOWNLOADING, progress)
            }

            override fun completed(task: BaseDownloadTask) {
                onDownloadSuccess(task.tag as DownloadTask, progressCallback, totalCount)
//                finalCounts++
//                log(String.format("[completed] tag[%s] oldFile[%B]",
//                        task.tag,
//                        task.isReusedOldFile))
//                log(String.format("---------------------------------- %s", task.tag))
//                updateStatus(task.tag, FileDownloadStatus.COMPLETED)
//                if (finalCounts == appVersionList.size) {
//                    castTime = System.currentTimeMillis() - castTime
//                    Log.i(TAG, castTime.toString())
//                }
            }

            override fun paused(task: BaseDownloadTask, soFarBytes: Int, totalBytes: Int) {
//                finalCounts++
                log(String.format("[paused] tag[%s] %d/%d", task.tag, soFarBytes, totalBytes))
                log(String.format("############################## %s", task.tag))
            }

            override fun error(task: BaseDownloadTask, e: Throwable) {
//                finalCounts++
                log(Html.fromHtml(String.format("[error] tag[%s] %s %s",
                        task.tag,
                        e,
                        FileDownloadUtils.getStack(e.stackTrace, false))))

                log(String.format("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! %s", task.tag))
                updateStatus(task.tag, FileDownloadStatus.DOWNLOAD_ERROR)
                onDownloadFailed(task.tag as DownloadTask, progressCallback, totalCount)
            }
        }
    }

    private fun updateStatus(tag: Any, status: FileDownloadStatus, progress: Int = 0) {
    }

    private fun log(msg: CharSequence) {
        AWLog.i(TAG, msg.toString())
    }
}